import { forwardRef, useImperativeHandle, useRef, useState } from 'react';

import { useRequest } from 'ahooks';
import { Button, DatePicker, Drawer, Form, FormProps, Input, Space, TreeSelect } from 'antd';
import { DataNode } from 'antd/es/tree';
import dayjs from 'dayjs';

import { store } from '@/store';

import { ImportanceTypeObj, WorkTypeObj } from '@/enum/product';
import { orgDeptInfoTreeList } from '@/services/base/bumenguanlibumenxiangguanjiekou';
import { orgUserInfoVoPage } from '@/services/base/yonghuguanlixitongyonghujiekou';
import {
  proMeetingAdd,
  proMeetingGet,
  proMeetingUpdate
} from '@/services/bizApi/shengchanhuiyijiekou';
import { findIdByName } from '@/utils';
import { EditableProTable, ProColumns } from '@ant-design/pro-components';

import { BizObject } from './';

type DataSourceType = {
  key: React.Key;
  title?: string;
  readonly?: string;
  decs?: string;
  state?: string;
  created_at?: number;
  update_at?: number;
  children?: DataSourceType[];
};

type EditOpenBaseArgs = {
  /** 成功回调 */
  onSuccess?: () => void;
};

export type EditRef = {
  open: (
    arg:
      | (EditOpenBaseArgs & {
          type: 'add';
        })
      | (EditOpenBaseArgs & {
          type: 'edit';
          rowData: BizObject;
        })
      | (EditOpenBaseArgs & {
          type: 'detail';
          rowData: BizObject;
        })
  ) => void;
};

export type EditProps = {};

const Edit: React.ForwardRefRenderFunction<EditRef, EditProps> = (_, ref) => {
  const [form] = Form.useForm();
  // 弹窗开启状态
  const [open, setOpen] = useState(false);
  const [args, setArgs] = useState<ArgumentsType<EditRef['open']>[0]>();
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
  const [dataSource, setDataSource] = useState<readonly DataSourceType[]>([]);
  const treeDict = useRef<Record<number, DataNode>>({});
  const userInfo = useRequest(
    async () => {
      const res = await orgUserInfoVoPage({ page: 1, size: 1000 });

      return res?.data?.records?.map((item) => {
        return {
          label: item?.fullName,
          value: item?.id
        };
      });
    },
    {
      refreshDeps: []
    }
  );
  const tree = useRequest(async () => {
    treeDict.current = {};

    const res = await orgDeptInfoTreeList();

    const formatData = (data: BASE.OrgDeptInfoVo[]): DataNode[] => {
      const result: DataNode[] = [];

      data.forEach((item) => {
        const node: DataNode = {
          title: item.deptName,
          key: item.id!,
          // @ts-ignore
          value: item.id!,
          children: []
        };

        treeDict.current[item.id!] = node;

        if (item.child && item.child.length > 0) {
          node.children = formatData(item.child);
        }

        result.push(node);
      });

      return result;
    };

    return formatData(res.data || []);
  });

  const orgDeptInfo = useRequest(
    async () => {
      const res = await orgDeptInfoTreeList();

      return res?.data?.map((item) => {
        return {
          label: item?.deptName,
          value: item?.id
        };
      });
    },
    {
      refreshDeps: []
    }
  );
  const proMeeting = useRequest(
    async (id: string) => {
      const res = await proMeetingGet({ id });
      const data = res?.data;
      const meetingTime = dayjs(data?.meetingTime);
      // 回填数据
      form.setFieldsValue({
        ...res?.data,
        meetingTime
      });
      setDataSource(
        (data?.meetingTaskList?.map((item) => {
          return {
            ...item,
            key: item?.id
          };
        }) as unknown as DataSourceType[]) || []
      );
    },
    {
      manual: true
    }
  );

  const submit = useRequest(
    async ({ meetingTime, ...values }) => {
      if (!dataSource?.length) {
        store.app?.message.info('请添加任务详情');
        return;
      }
      const query = {
        ...values,
        meetingTime: dayjs(values?.meetingTime).format('YYYY-MM-DD HH:mm:ss'),
        meetingTaskList: dataSource
      };

      if (args?.type === 'edit' && args.rowData) {
        query.id = args.rowData.id;
      }

      await (args?.type === 'edit' ? proMeetingUpdate(query) : proMeetingAdd(query));

      args?.onSuccess?.();
      setOpen(false);
      setDataSource([]);

      store.app?.message.success(args?.type === 'edit' ? '编辑成功' : '新增成功');
    },
    {
      manual: true
    }
  );

  useImperativeHandle(ref, () => {
    return {
      open: (arg) => {
        setArgs(arg);
        setOpen(true);

        setTimeout(() => {
          // 编辑回填数据
          if ((arg?.type === 'edit' || arg?.type === 'detail') && arg?.rowData) {
            proMeeting.run(arg?.rowData?.id as unknown as string);
          } else {
            form.resetFields();
          }
        });
      }
    };
  });

  const onFinish: FormProps['onFinish'] = async (values) => {
    return submit.runAsync(values);
  };

  const onCancel = () => {
    if (submit.loading) {
      store.app?.message.info('正在提交中，请稍后');

      return;
    }

    setOpen(false);
    setDataSource([]);
  };
  // 仅保存
  const onSave = () => {
    form.submit();
  };

  const columns: ProColumns<DataSourceType>[] = [
    {
      title: '重要性',
      key: 'importance',
      dataIndex: 'importance',
      valueType: 'select',
      valueEnum: ImportanceTypeObj,
      formItemProps: {
        rules: [{ required: true, message: '请选择重要性' }]
      },
      width: 100,
      align: 'center'
    },
    {
      title: '任务内容',
      dataIndex: 'taskContent',
      valueType: 'textarea',
      fieldProps: {
        // showCount: true,
        autoSize: {
          minRows: 1
        }
      },
      formItemProps: {
        rules: [{ required: true, message: '请输入任务内容' }]
      },
      width: 150,
      align: 'center'
    },
    {
      title: '工作类型',
      dataIndex: 'taskType',
      valueType: 'select',
      valueEnum: WorkTypeObj,
      align: 'center',
      formItemProps: {
        rules: [{ required: true, message: '请选择工作类型' }]
      },
      width: 100
    },
    {
      title: '任务下发时间',
      dataIndex: 'taskDispatchTime',
      valueType: 'dateTime',
      align: 'center',
      width: 200,
      fieldProps: {
        style: {
          width: '100%'
        }
      },
      formItemProps: {
        rules: [{ required: true, message: '请选择任务下发时间' }]
      }
    },
    {
      title: '时限',
      dataIndex: 'period',
      valueType: 'digit',
      fieldProps: {
        style: {
          width: '100%'
        }
      },
      formItemProps: {
        rules: [{ required: true, message: '请输入时限' }]
      },
      width: 100,
      align: 'center'
    },
    {
      title: '安排日期',
      dataIndex: 'dispatchDate',
      valueType: 'date',
      align: 'center',
      width: 130,
      fieldProps: {
        style: {
          width: '100%'
        }
      },
      formItemProps: {
        rules: [{ required: true, message: '请选择安排日期' }]
      }
    },
    {
      title: '安排人',
      dataIndex: 'dispatchUserId',
      request: async () => {
        const res = await orgUserInfoVoPage({ page: 1, size: 1000 });

        return (
          res?.data?.records?.map((item) => {
            return {
              label: item?.fullName,
              value: item?.id
            };
          }) || []
        );
      },
      render: (text) => userInfo?.data?.filter((item) => item.value === text)?.[0]?.label,
      formItemProps: {
        rules: [{ required: true, message: '请选择安排人' }]
      },
      width: 100,
      align: 'center'
    },
    {
      title: '部门',
      dataIndex: 'dutyDeptId',
      valueType: 'treeSelect',
      width: 200,
      align: 'center',
      renderFormItem: () => {
        return (
          <TreeSelect
            treeData={tree.data}
            treeNodeFilterProp="title"
            showSearch
            placeholder="请选择部门"
            allowClear
            // multiple
          />
        );
      },
      renderText: (text) => {
        return findIdByName(tree?.data || [], text as unknown as string);
      },
      formItemProps: {
        rules: [{ required: true, message: '请选择部门' }]
      }
    },
    {
      title: '责任人',
      dataIndex: 'dutyUserId',
      dependencies: ['dutyDeptId'],
      request: async (params) => {
        const res = await orgUserInfoVoPage({
          page: 1,
          size: 1000,
          deptId: params?.dutyDeptId
        });

        return (
          res?.data?.records?.map((item) => {
            return {
              label: item?.fullName,
              value: item?.id
            };
          }) || []
        );
      },
      render: (text) => userInfo?.data?.filter((item) => item.value === text)?.[0]?.label,
      formItemProps: {
        rules: [{ required: true, message: '请选择责任人' }]
      },
      width: 100,
      align: 'center'
    },
    {
      title: '操作',
      valueType: 'option',
      width: 200,
      hidden: args?.type === 'detail',
      render: (text, record, _, action) => [
        <a
          key="editable"
          onClick={() => {
            if (args?.type === 'detail') return;
            action?.startEditable?.(record.key);
          }}
        >
          编辑
        </a>,
        <a
          key="delete"
          onClick={() => {
            if (args?.type === 'detail') return;
            setDataSource(dataSource.filter((item) => item.key !== record.key));
          }}
        >
          删除
        </a>
      ]
    }
  ];

  return (
    <Drawer
      title={
        {
          add: '新增会议',
          edit: '编辑会议',
          detail: '会议详情'
        }[args?.type as string]
      }
      extra={
        <>
          {args?.type !== 'detail' && (
            <Space>
              <Button
                type="primary"
                loading={submit.loading}
                disabled={submit.loading}
                onClick={onSave}
              >
                保存
              </Button>
              <Button onClick={onCancel} disabled={submit.loading}>
                取消
              </Button>
            </Space>
          )}
        </>
      }
      width="75%"
      open={open}
      onClose={onCancel}
    >
      <Form
        onFinish={onFinish}
        form={form}
        layout="horizontal"
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 14 }}
        disabled={args?.type === 'detail'}
        requiredMark={args?.type !== 'detail'}
        variant={args?.type === 'detail' ? 'borderless' : undefined}
      >
        <Form.Item
          label="主持人"
          name="host"
          rules={[
            {
              required: true,
              message: '请输入主持人'
            }
          ]}
        >
          <Input placeholder="请输入主持人" />
        </Form.Item>
        <Form.Item
          label="记录人"
          name="recorder"
          rules={[
            {
              required: true,
              message: '请输入记录人'
            }
          ]}
        >
          <Input placeholder="请输入记录人" />
        </Form.Item>
        <Form.Item
          label="会议时间"
          name="meetingTime"
          rules={[
            {
              required: true,
              message: '请选择会议时间'
            }
          ]}
        >
          <DatePicker style={{ width: '100%' }} showTime placeholder="请选择会议时间" />
        </Form.Item>
      </Form>

      <EditableProTable<DataSourceType>
        rowKey="key"
        headerTitle="任务详情"
        maxLength={5}
        scroll={{
          x: 960
        }}
        recordCreatorProps={{
          position: 'bottom',
          record: () => ({
            key: Date.now()
          })
        }}
        loading={false}
        toolBarRender={() => []}
        columns={columns}
        request={async () => ({
          data: [],
          total: 3,
          success: true
        })}
        value={dataSource}
        onChange={setDataSource}
        editable={{
          type: 'multiple',
          editableKeys,
          onSave: async (rowKey, data, row) => {
            // console.log(rowKey, data, row);
            // await waitTime(2000);
          },
          onChange: setEditableRowKeys
        }}
      />
    </Drawer>
  );
};

export default forwardRef(Edit);
